<template>
  <div ref="renderRef" :class="`lazy-render ${initRef ? '' : 'lazy-render-hidden'}`">
    <transition name="slide-fade">
      <div v-if="isRender">
        <slot></slot>
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, onUnmounted } from "vue";
import { useIntersectionObserver } from "@vueuse/core";
const emits = defineEmits(["render", "destroyed"]);
const renderRef = ref(null);
const isRender = ref(false);
const initRef = ref(false);
const { stop } = useIntersectionObserver(
  renderRef,
  (target, observer) => {
    const [{ isIntersecting }] = target;

    // 1、子元素是否可见
    isRender.value = isIntersecting;
    // console.log(target, observer, "useIntersectionObserver", isRender.value, "isIntersecting", isIntersecting);

    if (isIntersecting) {
      // 2、记录子元素是否进入过可见区域
      if (!initRef.value) {
        initRef.value = true;
      }
      // 渲染时的回调
      emits("render", observer);
    } else {
      // 3、元素退出可见区域时，记录此时的高度，优化页面交互效果
      const {
        offsetHeight,
        style: { height }
      } = renderRef.value;
      if (offsetHeight > height && initRef.value) {
        renderRef.value.style.height = `${offsetHeight}px`;
      }
      // 销毁时的回调
      emits("destroyed", observer);
    }
  },
  {
    threshold: 0,
    rootMargin: "300px"
  }
);
onUnmounted(() => {
  stop();
});
</script>
<style lang="scss" scope>
.lazy-render {
  width: 100%;
  padding: 4px;
  &.lazy-render-hidden {
    padding: 30px 0;
  }
}
/*
  ！！！添加元素渲染动画效果，避免元素加载过于生硬，页面闪动
*/
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}
.slide-fade-enter-from {
  transform: translateX(20px);
  opacity: 0;
}
</style>
